/*  File Name	: Acceptor.cpp
 *  Author		: Javie Pong
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2012-3-20
 *  Description:
 */
#ifndef ACCEPTOR_CPP_
#define ACCEPTOR_CPP_
#include "Acceptor.h"

template<class SVC_HANDLER,class PEER_ACCEPTOR>
Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::Acceptor(Reactor *reactor,
		int port,std::string ip)
{
	this->ip_ = ip;
	this->port_ = port;
	this->reactor(reactor);
	this->is_open_ = false;

	if (port != 0)
	{
		LOG((DEBUG_LOG,"Acceptor::Acceptor-->open"));
		if(this->open(port, reactor, ip) != 0)
		{
			LOG((ERROR_LOG,"Acceptor::Acceptor-->open error"));
		}
	}
}

template<class SVC_HANDLER,class PEER_ACCEPTOR>
Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::~Acceptor()
{

}
#include "Sock.h"
template<class SVC_HANDLER,class PEER_ACCEPTOR>
int Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::open(int port,
		Reactor *reactor,std::string ip)
{
	if(NULL==reactor || 0==port || this->is_open_)
	{
		LOG((ERROR_LOG,"Acceptor::open-->error [%d][%d]",port,this->is_open_));
		//errno = EINVAL;
		return -1;
	}
	this->is_open_ = true;

	//initialize socket：bind(),listen(),setsockopt()
	this->ip_ = ip;
	this->port_ = port;
	if(this->acceptor_.open(port,ip)!=0)
	{
		this->is_open_ = false;
		return -1;
	}

	//enable non-block mode
	this->acceptor_.enable(O_NONBLOCK);

	//register to reactor
	//LOG((DEBUG_LOG,"Acceptor::open-->register_handler [%d]",
	//		this->acceptor_.get_handle()));
	int result= reactor->register_handler(this->acceptor_.get_handle(),
			this,EventHandler::ACCEPT_MASK);
	if (result < 0)
	{
		LOG((ERROR_LOG,"Acceptor::open-->register_handler error"));
		this->acceptor_.close();
		return -1;
	}
	this->reactor(reactor);
	return 0;
}

template<class SVC_HANDLER,class PEER_ACCEPTOR>
const int Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::get_handle(void)
{
	return this->acceptor_.get_handle();
}

template<class SVC_HANDLER,class PEER_ACCEPTOR>
const PEER_ACCEPTOR & Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::acceptor(void)
{
	return this->acceptor_;
}

template<class SVC_HANDLER,class PEER_ACCEPTOR>
int Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::handle_input(int handle)
{
	SVC_HANDLER *svc = NULL;
	if(this->make_svc_handler(svc)!=0)
	{
		return -1;
	}
	if(this->accept_svc_handler(svc)!=0)
	{
		return -1;
	}
	if(this->active_svc_handler(svc)!=0)
	{
		return -1;
	}
	return 0;
}

template<class SVC_HANDLER,class PEER_ACCEPTOR>
int Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::make_svc_handler(SVC_HANDLER *&svc)
{
	if(NULL==svc)
	{
		svc = new SVC_HANDLER();
		if(NULL==svc)
		{
			LOG((ERROR_LOG,"Acceptor::make_svc_handler error"));
			return -1;
		}
	}
	svc->reactor(this->reactor());
	return 0;
}

template<class SVC_HANDLER,class PEER_ACCEPTOR>
int Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::accept_svc_handler(SVC_HANDLER *svc)
{
	if(this->acceptor_.accept(svc->peer(),0)<0)
	{
		LOG((ERROR_LOG,"accept_svc_handler error"));
		return -1;
	}
	return 0;
}

template<class SVC_HANDLER,class PEER_ACCEPTOR>
int Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::active_svc_handler(SVC_HANDLER *svc)
{
//	int result = svc->open(this->reactor());
//	return result;

	if(svc->open(this->reactor())<0)
	{
		LOG((ERROR_LOG,"active_svc_handler error"));
		return -1;
	}
	return 0;
}

template<class SVC_HANDLER,class PEER_ACCEPTOR>
int Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::handle_output(int handle)
{
	return 0;
}

template<class SVC_HANDLER,class PEER_ACCEPTOR>
int Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::handle_close(int handle,ReactorMask mask)
{
	return 0;
}

template<class SVC_HANDLER,class PEER_ACCEPTOR>
int Acceptor<SVC_HANDLER,PEER_ACCEPTOR>::handle_timeout(void)
{
	LOG((DEBUG_LOG,"Acceptor::handle_timeout"));
	return 0;
}

#endif /*ACCEPTOR_CPP_*/
